#ifndef RPC_CONNECTION_HPP
#define RPC_CONNECTION_HPP

namespace rpc_connection{

struct rpc_connection_tcp{
	static const int socket_type = SOCK_STREAM;
	static const int protocol = IPPROTO_TCP;
	static inline CLIENT *create_client(struct sockaddr_in *addr, unsigned long prognum, unsigned long versnum, int *sockp);
	static inline SVCXPRT *create_service(int sockd); 
	static inline bool_t register_service(SVCXPRT *xprt, unsigned long prognum, unsigned long versnum, void (*dispatch)(svc_req *, SVCXPRT *));
};

CLIENT *rpc_connection_tcp::create_client(struct sockaddr_in *addr, unsigned long prognum, unsigned long versnum, int *sockp) { 
	return clnttcp_create(addr, prognum, versnum, sockp, 0, 0); 
};

SVCXPRT *rpc_connection_tcp::create_service(int sockd){
	return svctcp_create(sockd, 0, 0);
};

bool_t rpc_connection_tcp::register_service(SVCXPRT *xprt, unsigned long prognum, unsigned long versnum, void (*dispatch)(svc_req *, SVCXPRT *)) {
	return svc_register(xprt, prognum, versnum, dispatch, protocol);
};

struct rpc_connection_udp{
	static const int socket_type = SOCK_DGRAM;
	static const int protocol = IPPROTO_UDP;
	static inline CLIENT *create_client(struct sockaddr_in *addr, unsigned long prognum, unsigned long versnum, int *sockp);
	static inline SVCXPRT *create_service(int sockd); 
	static inline bool_t register_service(SVCXPRT *xprt, unsigned long prognum, unsigned long versnum, void (*dispatch)(svc_req *, SVCXPRT *));
};

CLIENT *rpc_connection_udp::create_client(struct sockaddr_in *addr, unsigned long prognum, unsigned long versnum, int *sockp) { 
	struct timeval timeout;
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
       	return clntudp_create(addr, prognum, versnum, timeout, sockp); 
};

SVCXPRT *rpc_connection_udp::create_service(int sockd){
	return svcudp_create(sockd);
};

bool_t rpc_connection_udp::register_service(SVCXPRT *xprt, unsigned long prognum, unsigned long versnum, void (*dispatch)(svc_req *, SVCXPRT *)) {
	return svc_register(xprt, prognum, versnum, dispatch, protocol);
};

template <int PROT>
struct protocol_to_connection{
};

template <>
struct protocol_to_connection<IPPROTO_TCP>{
	typedef rpc_connection_tcp connection_t;
};

template <>
struct protocol_to_connection<IPPROTO_UDP>{
	typedef rpc_connection_udp connection_t;
};

}

#endif /* #ifndef RPC_CONNECTION_HPP */
